// import com.alibaba.druid.DbType;
// import com.alibaba.druid.sql.PagerUtils;
// import com.alibaba.druid.sql.SQLUtils;
// import com.alibaba.druid.sql.ast.*;
// import com.alibaba.druid.sql.ast.expr.*;
// import com.alibaba.druid.sql.ast.statement.*;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;
// import com.alibaba.druid.wall.spi.WallVisitorUtils;
// import com.alibaba.druid.wall.violation.ErrorCode;
// import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation;

// import java.util.List;

#include "WallVisitor.h"
#include "../sql/SQLUtils.h"


    // WallProvider getProvider();

    // List<Violation> getViolations();

    void addViolation(Violation_ptr violation);

    // bool isDenyTable(std::string name);

    std::string WallVisitor::toSQL(SQLObject_ptr obj) {
        return SQLUtils::toSQLString(obj, getDbType())->c_str();
    }

    // bool isSqlModified();

    // void setSqlModified(bool sqlModified);

    // bool isSqlEndOfComment();

    // void setSqlEndOfComment(bool sqlEndOfComment);

    // void addWallUpdateCheckItem(WallUpdateCheckItem item);

    // List<WallUpdateCheckItem> getUpdateCheckItems();

    // bool visit(SQLPropertyExpr x) {
    //     WallVisitorUtils.check(this, x);
    //     return true;
    // }

    // bool visit(SQLInListExpr x) {
    //     WallVisitorUtils.check(this, x);
    //     return true;
    // }

    // bool visit(SQLBinaryOpExpr x) {
    //     return WallVisitorUtils.check(this, x);
    // }

    // bool visit(SQLMethodInvokeExpr x) {
    //     WallVisitorUtils.checkFunction(this, x);
    //     return true;
    // }

    // bool visit(SQLSelectQueryBlock x) {
    //     WallVisitorUtils.checkSelelct(this, x);

    //     return true;
    // }

    // bool visit(SQLSelectGroupByClause x) {
    //     WallVisitorUtils.checkHaving(this, x.getHaving());
    //     return true;
    // }

    // // @Override
    // bool visit(SQLSelectItem x) {
    //     WallVisitorUtils.check(this, x);
    //     return true;
    // }

    // bool visit(SQLJoinTableSource x) {
    //     WallVisitorUtils.check(this, x);
    //     return true;
    // }

    // bool visit(SQLCreateTableStatement x) {
    //     WallVisitorUtils.check(this, x);
    //     return true;
    // }

    // bool visit(SQLAlterTableStatement x) {
    //     WallVisitorUtils.check(this, x);
    //     return true;
    // }

    // bool visit(SQLDropTableStatement x) {
    //     WallVisitorUtils.check(this, x);
    //     return true;
    // }

    // bool visit(SQLUpdateStatement x) {
    //     WallVisitorUtils.initWallTopStatementContext();
    //     WallVisitorUtils.checkUpdate(this, x);

    //     return true;
    // }

    // void endVisit(SQLUpdateStatement x) {
    //     WallVisitorUtils.clearWallTopStatementContext();
    // }

    // bool visit(SQLInsertStatement x) {
    //     WallVisitorUtils.initWallTopStatementContext();
    //     WallVisitorUtils.checkInsert(this, x);

    //     return true;
    // }

    // void endVisit(SQLInsertStatement x) {
    //     WallVisitorUtils.clearWallTopStatementContext();
    // }

    // bool visit(SQLDeleteStatement x) {
    //     WallVisitorUtils.checkDelete(this, x);
    //     return true;
    // }

    // void preVisit(SQLObject_ptr x) {
    //     WallVisitorUtils.preVisitCheck(this, x);
    // }

    // // @Override
    // bool visit(SQLSelectStatement x) {
    //     WallConfig config = getConfig();
    //     if (!config.isSelectAllow()) {
    //         this.getViolations()
    //                 .add(new IllegalSQLObjectViolation(ErrorCode.SELECT_NOT_ALLOW, "select not allow",
    //                         this.toSQL(x)));
    //         return false;
    //     }

    //     WallVisitorUtils.initWallTopStatementContext();

    //     int selectLimit = config.getSelectLimit();
    //     if (selectLimit >= 0) {
    //         SQLSelect select = x.getSelect();
    //         PagerUtils.limit(select, getDbType(), 0, selectLimit, true);
    //         setSqlModified(true);
    //     }
    //     return true;
    // }

    // void endVisit(SQLSelectStatement x) {
    //     WallVisitorUtils.clearWallTopStatementContext();
    // }

    // bool visit(SQLExprTableSource x) {
    //     WallVisitorUtils.check(this, x);

    //     if (x.getExpr() instanceof SQLName) {
    //         return false;
    //     }

    //     return true;
    // }

    // bool visit(SQLIdentifierExpr x) {
    //     WallConfig config = getConfig();
    //     std::string name = x.getName();
    //     name = WallVisitorUtils.form(name);
    //     if (config.isVariantCheck() && config.getDenyVariants().contains(name)) {
    //         getViolations().add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : " + name,
    //                 toSQL(x)));
    //     }
    //     return true;
    // }

    // bool visit(SQLUnionQuery x) {
    //     return WallVisitorUtils.checkUnion(this, x);
    // }

    // void endVisit(SQLDeleteStatement x) {
    //     WallVisitorUtils.clearWallTopStatementContext();
    // }

    // bool visit(SQLLimit x) {
    //     if (x.getRowCount() instanceof SQLNumericLiteralExpr) {
    //         WallContext context = WallContext.current();

    //         int rowCount = ((SQLNumericLiteralExpr) x.getRowCount()).getNumber().intValue();
    //         if (rowCount == 0) {
    //             if (context != null) {
    //                 context.incrementWarnings();
    //             }

    //             if (!getProvider().getConfig().isLimitZeroAllow()) {
    //                 this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.LIMIT_ZERO, "limit row 0",
    //                         this.toSQL(x)));
    //             }
    //         }
    //     }
    //     return true;
    // }

    // bool visit(SQLCreateTriggerStatement x) {
    //     return false;
    // }

    // bool visit(SQLSetStatement x) {
    //     return false;
    // }

    // bool visit(SQLCallStatement x) {
    //     return false;
    // }

    // bool visit(SQLCommentHint x) {
    //     if (x instanceof TDDLHint) {
    //         return false;
    //     }
    //     WallVisitorUtils.check(this, x);
    //     return true;
    // }

    // bool visit(SQLShowCreateTableStatement x) {
    //     std::string tableName = (x.getName()).getSimpleName();
    //     WallContext context = WallContext.current();
    //     if (context != null) {
    //         WallSqlTableStat tableStat = context.getTableStat(tableName);
    //         if (tableStat != null) {
    //             tableStat.incrementShowCount();
    //         }
    //     }
    //     return false;
    // }

